#include "QiliThemeApplier.h"

#include <QFile>

#include <QApplication>
#include <QPalette>
#include <QStyleHints>
#include <QMetaEnum>


QiliThemeApplier::QiliThemeApplier(QApplication *app, QiliSettings *settings)
    : mApp(app), mSettings(settings)
{
    mStyleHints = mApp->styleHints();
    QObject::connect(mStyleHints, &QStyleHints::colorSchemeChanged, this, &QiliThemeApplier::handleColorSchemeChanged);
}

void QiliThemeApplier::apply()
{
    auto mode = detect();
    auto modes = QMetaEnum::fromType<QiliSettings::ColorMode>();
    auto themeName = QString(modes.valueToKey(mode)).toLower();
    QFile theme(QString(":/themes/%1.css").arg(themeName));
    if (theme.open(QFile::ReadOnly)) {
        auto styles = theme.readAll();
        mApp->setStyleSheet(styles);
    }
    else {
        qFatal() << "Can't load theme style sheet: " << theme.fileName();
    }
}

QiliSettings::ColorMode QiliThemeApplier::colorMode() const
{
    return mColorMode;
}

void QiliThemeApplier::handleColorSchemeChanged(Qt::ColorScheme scheme)
{
    qDebug() << "Theme Changed: " << scheme;
    apply();
}

QiliSettings::ColorMode QiliThemeApplier::detect()
{
    if (mSettings->colorMode() != QiliSettings::Auto) {
        return mSettings->colorMode();
    }

    auto colorScheme = mStyleHints->colorScheme();
    if (colorScheme == Qt::ColorScheme::Dark) {
        return QiliSettings::Dark;
    }

    auto palette = mApp->palette();

    auto color = palette.color(QPalette::Window);
    // if the avg of float rgb value is lesss then threshold
    qreal threshold = 0.6;
    qreal factor = color.redF() + color.greenF() + color.blueF();
    // then, let's treat it as in dark mode
    if (factor / 3 < threshold) {
        return QiliSettings::Dark;
    }

    // fallback to light theme
    return QiliSettings::Light;
}
